package de.hbrs.ooka.beans;

import de.hbrs.ooka.entities.ConferenceEntity;
import de.hbrs.ooka.entities.PaperEntity;
import de.hbrs.ooka.entities.UserEntity;
import de.hbrs.ooka.exception.BadReputationException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

@Stateless
public class ConferenceBeanStateless implements ConferenceBeanStatelessLocal {

    @PersistenceContext(unitName = "CRS_PU")
    private EntityManager em;
    @EJB
    private PaperBeanStatelessLocal m_paperBean;
    @EJB
    private UserBeanStatelessLocal m_userBean;

    @Override
    public ConferenceEntity getConference(int id) {
        Query qu = em.createNamedQuery("findConferenceByID").setParameter("id", id);
        List<ConferenceEntity> resultList = qu.getResultList();

        if (resultList.size() != 1) {
            throw new IllegalArgumentException("Too many results: " + resultList.size());
        }

        return resultList.get(0);
    }

    @Override
    public ConferenceEntity getConference(String name) {
        Query qu = em.createNamedQuery("findConferenceByName", ConferenceEntity.class).setParameter("name", name);
        List<ConferenceEntity> resultList = qu.getResultList();

        if (resultList.size() != 1) {
            throw new IllegalArgumentException("Too many results: " + resultList.size());
        }

        return resultList.get(0);
    }

    @Override
    public List<ConferenceEntity> getAllConferences() {
        Query qu = em.createNamedQuery("findAllConferences", ConferenceEntity.class);
        return qu.getResultList();
    }

    @Override
    public ConferenceEntity addConference(UserEntity organizer, String name, String location, Date date, int maxParticip) throws BadReputationException {
        double reputation = this.m_userBean.getReputation(organizer);
        if (reputation > 3.0) {
            if (maxParticip > 200) {
                throw new BadReputationException(reputation, maxParticip);
            }
        }

        ConferenceEntity conf = new ConferenceEntity(name, location, new SimpleDateFormat("dd.MM.yyyy").format(date), maxParticip);
        conf.setOrganizer(organizer);
        em.persist(conf);

        return conf;
    }

    @Override
    public void addPaperToConference(ConferenceEntity conf, PaperEntity paper) {
        paper.setSubmittedConference(conf);
        conf.addPaper(paper);

        em.merge(conf);
    }

    @Override
    public void rateConference(ConferenceEntity c, UserEntity u, int rating) {
        c.addRating(u, rating);

        em.merge(c);
    }

    @Override
    public double getReputation(ConferenceEntity conf) {
        double sum = 0.0;
        for (Map.Entry<Integer, Double> e : conf.getReputationList().entrySet()) {
            sum += e.getValue().doubleValue();
        }

        return sum / (double) conf.getReputationList().size();
    }
}
